package me.exchange.com.modules.system.service.impl;


import me.exchange.com.modules.system.domain.Dept;
import me.exchange.com.modules.system.domain.User;
import me.exchange.com.modules.system.dto.DeptDto;
import me.exchange.com.modules.system.dto.DeptQueryCriteria;
import me.exchange.com.modules.system.mapper.DeptMapper;
import me.exchange.com.modules.system.repository.DeptRepository;
import me.exchange.com.modules.system.repository.UserRepository;
import me.exchange.com.modules.system.service.DeptService;
import me.exchange.com.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
* @author Zheng Jie
* @date 2019-03-25
*/
@Service
@CacheConfig(cacheNames = "dept")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private UserRepository userRepository;

    @Override
    @Cacheable
    public List<DeptDto> queryAll(DeptQueryCriteria criteria) {
        Sort sort = criteria.getSort();
        return deptMapper.toDto(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
    }
    @Override
    @Cacheable
    public Object queryAll(DeptQueryCriteria criteria, Pageable pageable){
        return PageUtil.toPage(deptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable));
    }

    @Override
    @Cacheable(key = "#p0")
    public DeptDto findById(Long id) {
        Dept dept = deptRepository.findById(id).orElseGet(Dept::new);
        ValidationUtil.isNull(dept.getId(),"Dept","id",id);
        return deptMapper.toDto(dept);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public DeptDto create(Dept resources) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        resources.setCAdminId(user.getId());
        resources.setCAdminTime(new Timestamp(System.currentTimeMillis()));
        resources.setIsdel(true);
        return deptMapper.toDto(deptRepository.save(resources));
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Dept resources) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        Dept dept = deptRepository.findById(resources.getId()).orElseGet(Dept::new);
        ValidationUtil.isNull( dept.getId(),"Dept","id",resources.getId());
        resources =(Dept)BeanUtil.merge(resources,dept);
        resources.setUAdminId(user.getId());
        resources.setUAdminTime(new Timestamp(System.currentTimeMillis()));
        deptRepository.save(resources);
    }
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(DeptQueryCriteria criteria) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        Dept dept = deptRepository.findById(criteria.getId()).orElseGet(Dept::new);
        ValidationUtil.isNull( dept.getId(),"Dept","id",criteria.getId());
        dept.setUAdminId(user.getId());
        dept.setUAdminTime(new Timestamp(System.currentTimeMillis()));
        dept.setId(dept.getId());
        dept.setEnabled(criteria.getEnabled());
        deptRepository.save(dept);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<DeptDto> deptDtos) {
        Dept dept = null;
        for (DeptDto deptDto : deptDtos) {
            dept = deptRepository.findById(deptDto.getId()).orElseGet(Dept::new);
            dept.setIsdel(false);
            deptRepository.save(dept);
        }
    }

    @Override
    public void download(List<DeptDto> deptDtos, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        Optional<User> c_user=null;
        Optional<User> u_user=null;
        for (DeptDto deptDTO : deptDtos) {
            Map<String,Object> map = new LinkedHashMap<>();
            c_user =userRepository.findById(deptDTO.getCAdminId());
            map.put("部门名称", deptDTO.getName());
            map.put("部门状态", deptDTO.getEnabled() ? "启用" : "停用");
            map.put("创建人", c_user.get().getUsername());
            map.put("创建日期", deptDTO.getCAdminTime());
            if(deptDTO.getUAdminId() != null){
                u_user =userRepository.findById(deptDTO.getUAdminId());
                map.put("修改人", u_user.get().getUsername());
                map.put("修改日期", deptDTO.getUAdminTime());
            }
            map.put("备注", deptDTO.getRemark());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

}